import math
class S5Code:
    variants = []
    def __init__(self):
        self.variants = self.get_def_variants()

    def Test(self, from_, to_):
        print "---Test------------------------------------------------------"
        for i in range(from_, to_):
            code = self.IntToCode(i)
            int = self.CodeToInt(code)
            print "%d %d %s"%(i, int, code)

    def CodeToInt(self, str):
        list = self.string_to_list(str)
        possitions = self.list_to_possitions(list, self.variants)
        D = self.possitions_to_int(possitions, len(coder.variants))
        return int(D)
    
    def IntToCode(self, D):
        possitions = self.int_to_possitions(D, len(self.variants))
        list = self.possitions_to_list(possitions, self.variants)
        str = self.list_to_string(list)
        return str
    
    def get_def_variants(self):
        default = []
        default.extend(range(48, 58))
        default.extend(range(65, 91))
        default.extend(range(97, 123))        
        return map(lambda x: chr(x), default)

    def list_to_possitions(self, list, variants):
        possitions = []
        for letter in list:
            exact_possition = -1
            for possition in range(len(variants)):
                if variants[possition] == letter:
                    exact_possition = possition
                    break
            if exact_possition == -1:
                raise TypeError('Wrong variants for this list')
            possitions.append(exact_possition)
        return possitions

    def possitions_to_list(self, possitions, variants):
        list = []
        for possition in possitions:
            exact_letter = ""
            for letter in variants:
                if variants[possition] == letter:
                    exact_letter = letter
                    break
            if exact_letter == "":
                raise TypeError('Wrong variants for this list')
            list.append(exact_letter)
        return list
    
    def int_to_possitions(self, D, p):
        if D <=0:
            return None
        Dp=[]
        i=0
        while D >= p:
            q1 = D % p
            Dp.append(D % p)
            D = D // p
        Dp.append(D)
        return Dp
    
    def possitions_to_int(self, Dp, p):
        if len(Dp) <= 0 or p <=0 :
            return None
        D = 0
        for i in range(len(Dp)):
            D = D + Dp[i]*math.pow(p, i)
        return D

    def string_to_list(self, str):
        list = []
        for letter in str:
            list.append(letter)
        list.reverse()
        return list
    
    def list_to_string(self, list):
        list.reverse()
        str = ""
        for letter in list:
            str += letter
        return str        
            

coder = S5Code()
